﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlServerCe;
using System.Data;

namespace ProgNetComponents.Data.SqlCe
{
    /// <summary>
    /// DataManager for Sql Server Compact Edition
    /// </summary>
    public class SqlCeDataManager : DataManager
    {
        private static Dictionary<SqlCeDataAdapter, AutoIncHelpClass> RowUpdateCommands = new Dictionary<SqlCeDataAdapter, AutoIncHelpClass>();
        private class AutoIncHelpClass
        {
            public SqlCeCommand Command
            {
                get;
                set;
            }
            public DataColumn IdColumn
            {
                get;
                set;
            }
        }
        /// <summary>
        /// Gets or sets Connection String used for each SqlCeDataManager with UseGlobalConnectionString set tu True
        /// </summary>
        public static string GlobalConnectionString
        {
            get;
            set;
        }
        /// <summary>
        /// Creates SqlCeSchemaChecker
        /// </summary>
        /// <returns></returns>
        protected override SchemaChecker CreateSchemaChecker()
        {
           return new SqlCeSchemaChecker(this);
        }
        /// <summary>
        /// Returns GlobalConnectionString
        /// </summary>
        /// <returns></returns>
        protected override string GetGlobalConnectionString()
        {
            return GlobalConnectionString;
        }
        /// <summary>
        /// Creates SqlCeCommandBuilder
        /// </summary>
        /// <param name="adapter"></param>
        /// <returns></returns>
        protected override System.Data.Common.DbCommandBuilder CreateCommandBuilder(System.Data.Common.DbDataAdapter adapter)
        {
            return new SqlCeCommandBuilder((SqlCeDataAdapter)adapter);
        }
        /// <summary>
        /// Creates SqlCeConnection
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        protected override System.Data.Common.DbConnection CreateConnection(string connectionString)
        {
            return new SqlCeConnection(connectionString);
        }
        /// <summary>
        /// Creates SqlCeDataAdapter
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="selectString"></param>
        /// <returns></returns>
        protected override System.Data.Common.DbDataAdapter CreateAdapter(System.Data.Common.DbConnection connection, string selectString)
        {
            SqlCeDataAdapter ad = new SqlCeDataAdapter(selectString, (SqlCeConnection)connection);
            ad.RowUpdated += new SqlCeRowUpdatedEventHandler(ad_RowUpdated);
            return ad;
        }

        private void ad_RowUpdated(object sender, SqlCeRowUpdatedEventArgs e)
        {
            if (e.Row != null &&
                e.Row.RowState == System.Data.DataRowState.Added &&
                e.Status == System.Data.UpdateStatus.Continue)
            {
                AutoIncHelpClass h = null;
                SqlCeDataAdapter ad = sender as SqlCeDataAdapter;
                if (RowUpdateCommands.ContainsKey(ad))
                {
                    h = RowUpdateCommands[ad];
                }
                else
                {
                    h = new AutoIncHelpClass();
                    h.Command = new SqlCeCommand("SELECT @@IDENTITY", e.Command.Connection);
                    foreach (DataColumn c in e.Row.Table.Columns)
                    {
                        if (c.AutoIncrement)
                        {
                            h.IdColumn = c;
                            break;
                        }
                    }
                    RowUpdateCommands.Add(ad, h);
                }
                if (h.IdColumn != null)
                {
                    h.Command.Transaction = e.Command.Transaction;
                    e.Row[RowUpdateCommands[ad].IdColumn.ColumnName] = h.Command.ExecuteScalar();
                }
            }
        }
        /// <summary>
        /// Creates SqlCeParameter
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        protected override System.Data.Common.DbParameter CreateParameter(string name, object value)
        {
            return new SqlCeParameter(name, value);
        }
    }
    /// <summary>
    /// Class to create SqlCeDataManager
    /// </summary>
    public class SqlCeDataManagerCreator : DataManagerCreator
    {
        /// <summary>
        /// Creates SqlCeDataManager
        /// </summary>
        /// <returns></returns>
        public override DataManager CreateManager()
        {
            return new SqlCeDataManager();
        }
    }
}
